package memory;

import com.sun.xml.internal.bind.v2.runtime.output.Pcdata;

import javafx.fxml.FXMLLoader;
import process.Process;

public class PCB {			//进程控制块
	private int pid;
	private int ax=0;			//主要寄存器储存的值
	private int pc=0;			//程序计数器 指向下一条指令 
	private int address;	//内存指针 指向程序地址	类型未定  不需要吧？ TODO
	private int size;
	private process.Process process;//指向的进程 
	
	private char type='?';//进程要申请的设备，但未得到而阻塞
											//程序状态字 
	private int psw_process_end = 0;	//程序结束end
	private int psw_clock_end = 0;		//时钟中断
	private int psw_io = 0;				//I/O设备中断
											//程序状态字
	public PCB() {
		super();
	}
	
	public PCB(int pid,int address, int size) {
		super();
		this.pid = pid;
		this.address = address;
		this.size = size;
	}

	public static PCB register(int size) {
		int i = 0;
		if (PCBData.allPcbList.size() >= 10) {
			return null;
		} else {
			for (i = 0; i < PCBData.Blist.size(); i++) {
			
				if (PCBData.Blist.get(i).isFlag() == false) {
					if (PCBData.Blist.get(i).getSize() >= size) {
						break;
					}
				}
			}
			if (i >= PCBData.Blist.size()) {	
				return null;
			}
		}
		PCB pcb = new PCB(initialPid(), 0, size);
		int pid = pcb.getPid();
		for (i = 0; i < PCBData.Blist.size(); i++) {
			if (PCBData.Blist.get(i).isFlag() == false) {
				if (PCBData.Blist.get(i).getSize() > size) {
					Block temp = new Block(PCBData.Blist.get(i).getSize() - size, false, PCBData.Blist.get(i).getBegin(), 0);
					PCBData.Blist.get(i).setSize(size);
					PCBData.Blist.get(i).setFlag(true);
					PCBData.Blist.get(i).setPid(pid);
					if (i == 0)
						PCBData.Blist.get(i).setBegin(size);
					else
						PCBData.Blist.get(i).setBegin(PCBData.Blist.get(i - 1).getBegin() + size);
					PCBData.Blist.add(i + 1, temp);
					break;
				} else if (PCBData.Blist.get(i).getSize() == size) {
					PCBData.Blist.get(i).setFlag(true);
					PCBData.Blist.get(i).setPid(pid);
					break; 
				}
			}
		}
		if (i != 0)
			pcb.setAddress(PCBData.Blist.get(i - 1).getBegin());
		PCBData.allPcbList.add(pcb);
		PCBData.readyList.add(pcb);
		PCBData.str += pcb.toString()+"加载成功\n";
		return pcb;
	}
	
	public static PCB delete(int pid) {
		PCB pcb ;
		if (searchAllPCB(pid) ==-10){
			return null;
		} 
		else {
			int pcbindex = PCB.searchPCB(pid);
			int blockindex = searchBlock(pid);
			int allpcbindex =  PCB.searchAllPCB(pid);
			pcb = PCBData.allPcbList.get(allpcbindex);
			PCBData.str += PCBData.allPcbList.get(allpcbindex).toString() +"删除成功\n";
			PCBData.allPcbList.remove(allpcbindex);
			if(pcbindex!=-10)
				PCBData.readyList.remove(pcbindex);
			if(blockindex!=-10)
				PCBData.Blist.get(blockindex).setFlag(false);
			if (!PCBData.Blist.get(blockindex + 1).isFlag() && (blockindex + 1) < PCBData.Blist.size()) {
				PCBData.Blist.get(blockindex).setSize(PCBData.Blist.get(blockindex).getSize() + PCBData.Blist.get(blockindex + 1).getSize());
				PCBData.Blist.get(blockindex).setBegin(PCBData.Blist.get(blockindex + 1).getBegin());
				PCBData.Blist.remove(blockindex + 1);
			}
			if (blockindex >= 1 && !PCBData.Blist.get(blockindex - 1).isFlag()) {
				PCBData.Blist.get(blockindex - 1).setBegin(PCBData.Blist.get(blockindex).getBegin());
				PCBData.Blist.get(blockindex - 1)
						.setSize(PCBData.Blist.get(blockindex - 1).getSize() + PCBData.Blist.get(blockindex).getSize());
				PCBData.Blist.remove(blockindex);
			}
			
			return pcb;
		}
	}
	public static int initialPid() {
		int i,j;
		for(i = 0;i < 10 ;i++) {
			for( j = 0; j < PCBData.allPcbList.size();j++) {
				if(i==PCBData.allPcbList.get(j).getPid())
					break;
			}
			if(j>=PCBData.allPcbList.size()) {
				return i;
			}
		}
		return i;
	}

	public static int searchPCB(int pid) {
		for (int i = 0; i < PCBData.readyList.size(); i++) {
			if (PCBData.readyList.get(i).getPid()==pid) {
				return i;
			}
		}		
		return -10;
	}
	
	public static int searchBlock(int pid) {
		for(int i = 0; i < PCBData.Blist.size(); i++) {
			if (PCBData.Blist.get(i).getPid() == pid) {
				return i;
			}
		}
		return -10;
	}
	
	public static int searchAllPCB(int pid) {
		for (int i = 0; i <PCBData.allPcbList.size(); i++) {
			if (PCBData.allPcbList.get(i).getPid()==pid) {
				return i;
			}
		}		
		return -10;
	}

	@Override
	public String toString() {
			return "进程 [pid=" + pid +  ", address=" + address + ", size=" + size + "]";
	}
	public int getPid() {
			return pid;
	}
	public void setPid(int pid) {
			this.pid = pid;
	}
	public int getAx() {
			return ax;
	}
	public void setAx(int ax) {
			this.ax = ax;
	}
	public int getPc() {
		return pc;
	}

	public void setPc(int pc) {
		this.pc = pc;
	}

	public int getPsw_process_end() {
		return psw_process_end;
	}

	public void setPsw_process_end(int psw_process_end) {
		this.psw_process_end = psw_process_end;
	}

	public int getPsw_clock_end() {
		return psw_clock_end;
	}

	public void setPsw_clock_end(int psw_clock_end) {
		this.psw_clock_end = psw_clock_end;
	}

	public int getPsw_io() {
		return psw_io;
	}

	public void setPsw_io(int psw_io) {
		this.psw_io = psw_io;
	}

	public int getAddress() {
			return address;
	}
	public void setAddress(int address) {
			this.address = address;
	}
	public int getSize() {
		return size;
	}
	public void setSize(int size) {
		this.size = size;
	}

	public char getType() {
		return type;
	}

	public void setType(char type) {
		this.type = type;
	}

	public process.Process getProcess() {
		return process;
	}

	public void setProcess(Process process) {
		this.process = process;
	}	
	
}
